package com.newbee.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * HTTP 请求头中提取链路信息的工具类
 */
@Slf4j
public class HttpTraceHeaderUtil {

    // 约定的请求头名称（建议与前端/其他服务保持一致）
    private static final String TRACE_ID_HEADER = "X-Trace-Id";

    /**
     * 从当前请求头中获取 traceId（若不存在则返回 null）
     */
    public static String getTraceIdFromHeader() {
        // 第一层：判断是否存在请求上下文
        Object requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) {
            log.debug("无请求上下文，无法从请求头获取 traceId（非 Web 环境）");
            return null;
        }

        // 第二层：判断上下文类型是否匹配（避免类型转换异常）
        if (!(requestAttributes instanceof ServletRequestAttributes)) {
            log.warn("请求上下文类型不匹配，预期 ServletRequestAttributes，实际：{}", requestAttributes.getClass().getName());
            return null;
        }

        ServletRequestAttributes servletAttrs = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request;
        try {
            // 第三层：获取 request 并判断是否可用
            request = servletAttrs.getRequest();

            // 第四层：获取请求头（处理容器级异常）
            return request.getHeader(TRACE_ID_HEADER);
        } catch (IllegalStateException e) {
            // 捕获请求已提交/销毁的异常
            log.warn("获取请求头失败：请求已被容器销毁（{}）", e.getMessage());
            return null;
        } catch (Exception e) {
            // 捕获其他未预料的异常（如容器内部异常）
            log.error("从请求头提取 traceId 时发生未知异常", e);
            return null;
        }
    }
}
